<?php
/**
 * Display a set of variants of a given text span in a given 
 * version.
 */
// no direct access
defined( '_JEXEC' ) or die( 'Restricted access' );
$windowboxId = $attribs['windowboxId'];
$collapsePath = $attribs['collapsePath'];
$expandPath = $attribs['expandPath'];
$displayboxId = $attribs['displayboxId'];
$base = $attribs['base'];
$mvd = $attribs['mvd'];
$rawelem = $attribs['rawelem'];
?>
<div id="<?php echo $windowboxId;?>" class="windowbox" 
	style="height:120px; overflow:hidden; display:none">
<script type="text/javascript">
var timerLen = 50;
var slideAnimationLen = 250;
var timerID = new Array();
var startTime = new Array();
var obj = new Array();
var endHeight = new Array();
var startHeight = new Array();
var moving = new Array();
var direction = new Array();
var myRequest = false;
/**
 * Get the border-top width of an element
 * @param id the id of the element 
 * @return the border width as an int
 */
function getBorderTopWidth( id )
{
	var style = getStyle( id, "border-top-width" );
	var number = "";
	for ( var i=0;i<style.length;i++ )
	{
		var token = style.charAt(i);
		if ( token >= '0' && token <= '9' )
			number += token;
	}
	return parseInt( number );
}
/**
 * Decide whether to scroll the windowbox up or down
 * @param buttonId the id of the button we pressed to get here
 * @param objid the id of the div to reveal/hide
 * @param dispid id of the main display block this windowbox 
 * belongs to
 */
function doVariants( buttonId, objid, dispid )
{
	var button = document.getElementById(buttonId);
	var openTitle = "<?php echo JText::_('WINDOWBOX_OPEN');?>";
	var closeTitle = "<?php echo JText::_('WINDOWBOX_CLOSE');?>";
	var collapseIcon = "<?php echo JURI::base().$collapsePath;?>";
	var expandIcon = "<?php echo JURI::base().$expandPath;?>";
	if ( !button.readonly )
	{
		slideout( objid, dispid );
		button.title = closeTitle;
		button.setAttribute("style",
			"width:28px;height:28px;background-image:url('"
			+collapseIcon+"')");
	}
	else
	{
		slidein( objid, dispid );
		button.title = openTitle;
		button.setAttribute("style",
			"width:28px;height:28px;background-image:url('"
			+expandIcon+"')");
	}
	button.readonly = !button.readonly;
}
/**
 * Initiate slideout in response to user click
 * @param objid the id of the object to expand
 * @param dispid id of the main display block
 */
function slideout( objid, dispid )
{
	if ( !moving[objid]
		&& document.getElementById(objid).style.display 
			!= "block")
	{ 
		moving[objid] = true;
		direction[objid] = "out";
		startslide( objid, dispid );
	}
}
/**
 * Initiate slidein in response to user click
 * @param objid the id of the object to collapse
 * @param dispid id of the main display block
 */
function slidein( objid, dispid )
{
	if ( !moving[objid]
		&& document.getElementById(objid).style.display 
			!= "none" )
	{
		moving[objid] = true;
		direction[objid] = "in";
		startslide( objid, dispid );
	}
}
/**
 * Set up a slide by setting a js interval to call slidetick.
 * Take account of the border width
 * @param objid the id of the object to slide out/in
 * @param dispid id of the main display block
 */
function startslide( objid, dispid )
{
	var topWidth = getBorderTopWidth(objid);
	obj[objid] = document.getElementById(objid);
	obj[dispid] = document.getElementById(dispid);
	endHeight[objid] = parseInt(obj[objid].style.height);
	startHeight[dispid] = parseInt(obj[dispid].style.height);
	startTime[objid] = new Date().getTime();
	if ( direction[objid] == "out" )
	{
		endHeight[dispid] = startHeight[dispid]
			- (endHeight[objid]+topWidth);
	}
	else
	{
		endHeight[dispid] = startHeight[dispid] 
			+ topWidth + endHeight[objid];
	}
	timerID[objid] = setInterval( 
		"slidetick('"+objid+"','"+dispid+"','"+topWidth+"');",timerLen );
}
/**
 * Increment the degree of the slide by altering the height 
 * of the object until we run out of time. This is called  
 * every timerLen milliseconds!
 * @param objid the id of the object to slide out/in
 * @param dispid id of the main display block
 * @param topWidth the thickness of the top border
 */
function slidetick( objid, dispid, topWidth )
{
	var elapsed = new Date().getTime() - startTime[objid];
	if ( elapsed > slideAnimationLen )
		endSlide( objid, dispid );
	else 
	{
		var d = Math.round( elapsed/slideAnimationLen
			* endHeight[objid] );
		if ( direction[objid] == "in" )
		{
			obj[dispid].style.height = (startHeight[dispid]+d)+"px";
			d = endHeight[objid]-d;
		}
		else
			obj[dispid].style.height = ((startHeight[dispid]-d)-topWidth)+"px";
		obj[objid].style.height = d+"px";
		if ( obj[objid].style.display = "none" )
			obj[objid].style.display = "block";
	}
}
/**
 * Clean up after a slide and kill the interval
 * @param objid the id we are sliding
 * @param dispid id of the main display block
 */
function endSlide( objid, dispid )
{
    clearInterval(timerID[objid]);
    if ( direction[objid] == "in" )
		obj[objid].style.display = "none";
	else
		obj[objid].style.overflow = "auto";
	obj[dispid].style.height = endHeight[dispid]+"px";
	// windowbox may be hidden but its height is full
	obj[objid].style.height = endHeight[objid]+"px";
    delete( moving[objid] );
    delete( timerID[objid] );
    delete( startTime[objid] );
    delete( endHeight[objid] );
    delete( endHeight[dispid] );
    delete( obj[objid] );
    delete( obj[dispid] );
    delete( direction[objid] );
}
/**
 * Store information about a user selection
 */
function UserRange()
{
	this.top = 0;
	this.bottom = 0;
	this.isEmpty = selectionIsEmpty;
	this.createDefault = createDefaultSelection;
	this.adjustOffsets = adjustSelectionOffsets;
}
function adjustOffset( offset )
{
	var realOffset = offset;
	if ( document.adjustments != null && document.offsets != null )
	{
		for ( var i=0;i<document.offsets.length;i++ )
		{
			if ( document.offsets[i] < offset )
			{
				realOffset = offset - document.adjustments[i];
				break;
			}
		}
	}
	return realOffset;
}
/**
 * Use the documents adjustments and offsets arrays if available 
 * to adjust a given 'offset' into the visible text, so that it 
 * precisely matches the offset into the real XML data. 
 */
function adjustOffsets()
{
	this.top = this.adjustOffset( this.top );
	this.bottom = this.adjustOffset( this.bottom );
}
/** 
 * Is the selection empty?
 */
function selectionIsEmpty()
{
	return this.top==0 && this.bottom==0;
}
/**
 * Create a default selection based on a central band.
 * @param div the div whose central band is to be computed.
 */
function createDefaultSelection( div )
{
	var mainDivHeight = getMainDivHeight();
	var upperLimit = div.scrollTop + (mainDivHeight/4) + div.offsetTop;
	var lowerLimit = div.scrollTop + ((mainDivHeight*3)/4) + div.offsetTop;
	this.top = (upperLimit*div.innerHTML.length)/div.scrollHeight;
	this.bottom = (lowerLimit*div.innerHTML.length)/div.scrollHeight;
}
function adjustOffsets()
{
}
/**
 * Send an ajax call to the controller requesting variants
 * for the given range. Populate the windowbox with the contents.
 * @param range a UserRange
 * @param raw "raw" if raw format desired, otherwise ""
 */
function computeVariants( range, raw )
{
	// the format has to be raw, or it will wrap the output in HTML
	var len = range.bottom - range.top;
	var myUrl='<?php echo JURI::base()."index.php?option=com_mvd&format=raw&task=variants"?>'+raw+'<?php echo "&name=$mvd&base=$base&offset="?>'+range.top+"&length="+len;
	if ( window.XMLHttpRequest )
	{
		myRequest = new XMLHttpRequest();
		if ( myRequest.overrideMimeType )
			myRequest.overrideMimeType('text/plain');
	}
	else if ( window.ActiveXObject )
	{
		try 
		{
			myRequest = new ActiveXObject("Msxm12.XMLHTTP");
		}
		catch ( e )
		{
			try
			{
				myRequest = new ActiveXObject("Microsoft.XMLHTTP");
			}
			catch ( e )
			{
			}
		}
	}
	if ( !myRequest )
	{
		alert("Cannot create XMLHTTP object" );
		return false;
	}
	// every time readyState changes this will be called
	myRequest.onreadystatechange = displayReturn;
	// send the http request
	myRequest.open('GET', myUrl, true );
	myRequest.send( null );
}
/**
 * Set the text of the variants area. This is called when we get 
 * a valid Ajax response.
 */
function displayReturn()
{
	if ( myRequest.readyState == 4 )
	{
		if ( myRequest.status == 200 )
		{
			var p = document.getElementById("<?php echo $windowboxId.'Content';?>");
			p.innerHTML = "<p>"+myRequest.responseText+"</p>";
		}
	}
}
/**
 * Decide which method to use to retrieve variants.
 */
function reportSelection() 
{
	if ( "<?php echo $rawelem;?>".length > 0 )
		reportSelectionRaw();
	else
		reportSelectionHTML();
}
/**
 * Report on a raw selection - no milestones available
 */
function reportSelectionRaw() 
{
	var selLeft = 0;
	var selRight = 0;
	var range = new UserRange();
	var editBox = document.getElementById("<?php echo $rawelem;?>");
	if ( editBox.selectionStart == editBox.selectionEnd )
	{
		// compute an approximate start and end offset
		// for the central band
		var ta = document.getElementById('<?php echo $rawelem;?>');
		var height = ta.scrollHeight;
		var lineHeight = getStyleValue('<?php echo $rawelem;?>','line-height');
		var boxHeight = getStyleValue('<?php echo $rawelem;?>','height');
		var nLines = height / lineHeight;
		var textLen = ta.value.length;
		var top = ta.scrollTop+boxHeight/3;
		var bottom = top + boxHeight/3;
		selLeft = Math.round((textLen*top)/height);
		selRight = Math.round((textLen*bottom)/height);
	}
	else
	{
		selLeft = editBox.selectionStart;
		selRight = editBox.selectionEnd;
	}
	// convert html offsets to xml offsets
	range.top = selLeft;
	range.bottom = selRight;
	range.adjustOffsets();
	computeVariants( range, "raw" );
}
/**
 * Get the selection or the central band if no selection and 
 * retrieve the variants from the MVD for the current version 
 * as a base text. 
 */
function reportSelectionHTML() 
{
	var box = document.getElementById("<?php echo $windowboxId;?>");
	if ( box.style.display =='block' )
	{
		var div = document.getElementById("<?php echo $displayboxId;?>");
		var selRange = getSelection();
		if ( selRange.isEmpty() )
			selRange.createDefault( div );
		selRange.adjustOffsets();
		computeVariants( selRange, "" );
	}
}
function elemToPageTop( elem )
{
	var dist = 0;
	var temp = elem;
	while ( temp != null )
	{
		dist += temp.offsetTop;
		temp = temp.offsetParent;
	}
	return dist;
}
document.onmouseup = reportSelection;
</script>
<p id="<?php echo $windowboxId.'Content';?>">
</p>
</div>
